home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d18
/
moustool.arc
/
MOUSTOOL.DOC
< prev
next >
Wrap
Text File
|
1989-05-10
|
20KB
|
463 lines
╔═══════════════════════════════════════════════════════════════════════════╗
║ ║
║ MouseTools ║
║ Version 1.0 April 7, 1989 ║
║ ║
║ Nels Anderson ║
║ 92 Bishop Drive ║
║ Framingham, MA 01701 ║
║ ║
╚═══════════════════════════════════════════════════════════════════════════╝
The use of a mouse as an input device is becoming increasingly common in
many types of programs. While this (usually) makes life easier for the
user, it certainly does make the programmer's job harder. Several things
I've worked on seemed to demand a mouse interface, so I ended up writing
my own utilities to use a mouse and I present them in this package for
you to use in your own Turbo Pascal 5.0 programs.
This set of utilities provides most of the necessary procedures to use
a mouse in your own programs, including:
o display the mouse cursor
o read mouse and button positions
o display various prompts with "push buttons"
o select filenames
To use these tools you will need Turbo Pascal 5.0 and you must have the
TP5 units Crt, Dos, Drivers, Fonts and Graph available. I've provided you
with two sample programs (mapedit.pas, cgaexp.pas) along with the .tpu
files for all the mouse tools. This should give you enough to get started
writing mouse programs in Turbo Pascal. The source code for the units is
not included.
MouseTools is provided as Shareware. You may use it, copy it for friends,
upload it to BBS's, etc. If you continue to use MouseTools and would like
to reward me for my work, you can send a donation ($10 suggested) to me
at:
Nels Anderson
92 Bishop Drive
Framingham, MA 01701
Registered users will get the latest updates on the tools as well as the
source code for all the mouse units. Support is also available through
my BBS, )(evious, at 508-875-3618 or 617-449-7322, 300/1200/2400/9600HST.
I'd love to see anything you create using these tools; if you can either
mail me a copy or upload it to the BBS.
If you're connected to one of the minicomputer nets (InterNet, uucp...)
you can try reaching me at one of these addresses:
ima!primerd!en-m32.prime.com!nja
uunet!en-m32.prime.com!nja
csnet-relay!en-m32.prime.com!nja
nja%en-m32.prime.com@relay.cs.net
nja@en-m32.prime.com
╔═══════════════════════════════════════════════════════════════════════════╗
║ Using MouseTools ║
╚═══════════════════════════════════════════════════════════════════════════╝
Probably the best way to understand how the tools work is to examine the
sample programs, mapedit.pas and cgaexp.pas. You should refer to them for
actual examples of how things are used as they are described here.
First, some basic concepts. Most of your interface to the mouse is
actually done by the mouse driver that is supplied by the mouse manu-
facturer. The interface to the mouse driver is done through interrupts
similar to the way MS-DOS or BIOS functions are accessed. If you've
never used MS-DOS/BIOS functions, don't worry. MouseTools handles all
the messy details for you.
Once the mouse is activated and you can read positions from it, your
program needs to display something on the screen to echo the mouse's
actions. MouseTools allows you to use any shape as a mouse cursor,
and comes with an arrow, finger and hand cursor already drawn. With
the registered version you can add your own cursor shapes. Tools are
provided for displaying and moving the cursor around the screen.
In addition to movement, you need to determine when the user wants to
do something either by just being over a particular part of the screen
or by using the mouse buttons. These are the basic tools of the mouse
interface.
In addition to the basics, tools are provided to display prompts of
several types and return the selections the user made. One of the most
sophisticated prompts is the file selection tool, which allows the user
to select files through a scrolling list and includes the ability to
change directories and drives.
OK, so all these tools are available. Now you're probably wondering
exactly how to use them. Let's go through that step by step.
INITIALIZATION
First, you must enter graphics mode as you would in any Turbo Pascal
program. Then the mouse itself must be initialized. The functions
to do this are:
MReset -- resets the mouse and returns -1 if a mouse driver is installed
MLimit (x1,x2,y1,y2) -- sets the limits of the mouse coordinates
MPut(x,y) -- positions the mouse at coordinates x,y
If MReset doesn't return a value of -1 there is no mouse driver installed
and your program won't be able to do any mouse functions. MLimit is used
to control the range of values the mouse returns to you. These limits
will probably be equal to the size of the screen (i.e., x=0 thru 639,
y=0 thru 349 for EGA graphics mode). MPut sets the mouse coordinates to
start from. You'll probably want to either put the mouse in a corner or
in the middle of the screen.
Several Pascal variables are used to keep track of what the mouse has
been doing. These are:
Mx -- last mouse x coordinate \
My -- last mouse y coordinate > all are in mouse.tpu
Button -- last mouse button value /
Initially, you should set Mx and My to the values you used in MPut(x,y),
and you should initialize Button to 0.
You'll also need some memory on the heap to save the screen that's under
the mouse cursor. The variable MCurs (in mouse.tpu) is used to point to
this memory. Set it up by using:
GetMem(MCurs,ImageSize(0,0,MW,MH)); {reserve memory for mouse cursor}
There's still no visible indication on the screen that there's a mouse
in use. You can now turn on the mouse cursor using the procedure:
MouseCursorOn(Mx,My,HAND); {display a hand cursor}
The first two parameters determine where the mouse cursor will be.
The third parameter determines the shape of the mouse cursor. The
available cursor shapes are HAND, FINGER and ARROW.
Now everything is set, and you can start the main body of your program.
USING THE MOUSE IN YOUR MAIN PROGRAM
The main body of your program will need a loop where the mouse is
polled allowing its displayed position to be updated and to check
for command requests from the user.
The main procedure in this loop is:
MStatus(NewButton,NewX,NewY); {get mouse status}
This returns the current position of the mouse buttons followed by the
x and y mouse coordinates. There are several things you can then do
with this information:
* Compare NewX vs. Mx and NewY vs. My to see if the mouse has moved.
If it has, use:
MouseCursor(NewX,NewY,Mx,My,HAND); {move mouse cursor}
to move the mouse cursor to its new position. After moving, save NewX
into Mx and NewY into My.
* See if the mouse is over something significant by using:
MouseLocate(NewX,NewY,18,@mt)
This function uses a table ("mt" in this case, containing 18 items)
of coordinates and returns a value indicating which if any sets of
coordinates NewX/NewY are within. MouseLocate() is further described
later.
* See if a button is being pushed by comparing NewButton with
Button. Detecting a button push will usually mean a call to
MouseLocate() to find what item the user is selecting. Then
a case statement can be used to call the appropriate procedure.
Believe it or not, that's basically it! The remainder of this file will
describe in detail what all the available functions and procedures do.
MOUSETOOLS DETAILED DESCRIPTIONS
Once you understand the basics of initializing the mouse and detecting
what it's doing in the body of the program, you'll need to know what
tools are available for using it further. This section describes in
detail all the available mouse functions and procedures, in order by
the unit they are in.
MOUSE.TPU
This unit provides the interface to the mouse driver, plus the basic
routines for displaying the mouse cursor and determining what the
mouse is pointing to.
function MReset: INTEGER;
This function initializes the mouse. It returns an integer value of
-1 if a mouse is detected. If MReset does not return -1, you cannot
use mouse functions in the remainder of the program.
procedure MPut(mx,my: INTEGER);
This procedure sets the current mouse position to mx,my. That is, if
you were to immediately read the mouse position using MStatus() before
the user had a chance to move it, the values you'd receive back would
be mx,my.
procedure MStatus(var button,xpos,ypos: INTEGER);
This procedure returns the current state of the mouse. "Button" is a
bit mapped value indicating which buttons are pressed (i.e., Button is
1 if button 1 is pressed, 2 if button 2 is pressed, 3 if both buttons
1 and 2 are pressed). xpos,ypos are the current position of the mouse.
procedure MLimit(xmin,xmax,ymin,ymax: INTEGER);
You can limit the coordinate values returned by MStatus using this
procedure. To prevent the mouse from going off the screen in EGA
640x350 mode, you could set xmin=0, xmax=639, ymin=0, ymax=349.
Smaller values can be used to limit mouse travel to only a portion
of the screen.
procedure MouseCursor(x,y,Oldx,Oldy,Num: INTEGER);
This procedure moves the displayed mouse cursor from one position,
Oldx,Oldy to a new position, x,y. Make sure the mouse cursor is
actually being displayed when you call this function, otherwise you
will leave blocks of garbage on the screen.
procedure MouseCursorOn(x,y,Num: INTEGER);
This procedure is basically one half of MouseCursor(). Use it when
the mouse cursor is not currently being displayed but now should be,
such as at the beginning of the program. MouseCursorOn() must be
used before MouseCursor() is first called.
procedure MouseCursorOff(Oldx,Oldy: INTEGER);
This procedure removes the mouse cursor from the screen and restores
whatever was under it to view.
function MouseLocate(x,y,size: INTEGER; mt: mtptr): INTEGER;
This function is the key to making the mouse do useful things within
your program. It uses a table "mt" with "size" entries in it to
determine what the user is pointing to. "x" and "y" should be the
current mouse coordinates (Mx and My).
To use MouseLocate you must set up a table of integers, 4 numbers
per entry, which describe rectangles on the screen. Here is a sample
table:
Const
mt: array[1..2,1..4] of INTEGER = (
(400,620,68,81), {save}
(400,620,82,95) ); {read}
The sample shows two possible functions, save and read, that the user
can select. If the x coordinate of the mouse is between 400 and 620,
and the y coordinate is between 68 and 81 then "save" is being
selected. MouseLocate will check all entries in the table and will
return the number of the first table entry found that contains the
specified coordinates.
Note that when calling MouseLocate you must actually pass a pointer
to the table rather than the table itself, so a sample call to
MouseLocate might look like this:
i := MouseLocate(Mx,My,18,@mt);
MOUSERS2.TPU
This unit provides several ways of prompting the user for input and
using the mouse to get his response.
function MGetFile(FileSpec,Heading: STRING): STRING;
This is a very sophisticated routine for allowing the user to select
file names. A box is popped up containing a list of files that the
user can select from. The list can be scrolled if all valid files
do not fit and the user can switch between directories and disks.
"FileSpec" specifies what file names will be shown. You'd use "*.*"
to show all files, but if you only wanted files with the suffix "pic"
you could set FileSpec to "*.pic". Many possibilities are available
for FileSpec. "Heading" is a prompt to the user that will be at the
top of the box showing the file names. MGetFile returns a string
containing the filename that was selected. If character 0 of the
returned string is equal to #255 however the user aborted the file
selection.
function MouseYN(x,y: INTEGER; Heading: STRING): BOOLEAN;
This function displays a question contained in "Heading" along with
a yes and no button. If the user selects the yes button, the
function returns a TRUE value, otherwise it returns false.
function MouseQuestion(Size: INTEGER;Heading: STRING;Ques: QTable): INTEGER;
This function displays a question and a list of answers for the user
to choose from, returning the number of the user's choice. "Size"
is the number of possible answers. "Ques" is an array of strings
containing the possible responses. A sample "Ques" might look like:
PalQues: array[1..5] of STRING = ( {palette questions}
'Save','Load','Change','Rotate','Default');
Note that when calling MouseQuestion you must actually pass a pointer
to the table rather than the table itself, so a sample call to
MouseQuestion might look like this:
case MouseQuestion(5,'Select a palette function',@PalQues) of
function MouseReadKey(Heading: STRING): CHAR;
This function displays a heading (actually, the heading is optional)
and waits for the user to hit a single key or click the mouse. If
a key is hit, its value is returned; otherwise if the mouse is
clicked a value of #0 is returned.
BOX.TPU
This unit has a couple of tools used for popup boxes and other things.
procedure OutlineBox(x1,y1,x2,y2,boxcolor,rectcolor: INTEGER);
This procedure draws a box using "boxcolor" as the background color
of the box, and using a single pixel wide outline of color "rectcolor"
around the edge. This is the standard box used for mouse prompts.
procedure XPutPixel(x,y,color: INTEGER);
Plot a pixel at x,y by XOR'ing its current color with "color".
procedure XLine(x1,y1,x2,y2,color: INTEGER);
Draw a line from x1,y1 to x2,y2 by XOR'ing its current color
with "color".
procedure Input(var temp: STRING);
String input routine for graphics mode. Handles echoing of the
string using the currently selected font as well as displaying a
cursor and backspacing.
PALETTE.TPU
This unit is not strictly part of the mouse tools, but is needed to
use EGA graphics mode. Its only procedure is one to initialize graphics
mode.
procedure Initialize;
As currently set up, Initialize sets up EGA 640x350 mode graphics.
This routine is right out of the Turbo Pascal sample programs, so if
you need other modes you should be able to make your own version of
it.
CONVERT.TPU
This unit isn't really necessary for a mouse interface either, but
contains some functions that I use in mapedit.pas and which you might
find useful.
function RtoI(number: REAL): INTEGER;
Takes the real variable "number" and returns it as an integer.
function ItoS(number: LONGINT): STRING;
Takes the integer variable "number" and returns it as a string.
function ItoFS(number: LONGINT; a: INTEGER; fill: CHAR): STRING;
Takes the integer variable "number" and returns it as a formatted
string, exactly "a" characters long with unneeded character positions
set to the character "fill".
function RtoS(number: REAL; a,b: INTEGER): STRING;
Takes the real variable "number" and returns it as a formatted
string, exactly "a" characters long with "b" characters after the
decimal point.
function NoSpace(s: STRING): STRING;
Takes the string "s" and returns it with leading spaces removed.
function GetVal(s: STRING): REAL;
Takes the string "s" and returns it as a real number.
╔═══════════════════════════════════════════════════════════════════════════╗
║ Sample Programs ║
╚═══════════════════════════════════════════════════════════════════════════╝
MapEdit, one sample program used to demonstrate MouseTools, is actually
a utility I wrote for a friend who needed to be able to draw icons that
would be combined to create a map display in a program he was writing.
Another friend has since used MapEdit to draw the keys for a calculator
program he is writing. I haven't used any MapEdit icons in any released
programs *yet* but I'm working on an adventure game that will use maps
and creatures created with MapEdit. So, in addition to a sample of the
mouse tools you're getting a potentially useful program since there are
lots of possible uses for graphical icons.
I've included a sample icon file called ccmap.pic for you to play around
with. This is some of the icons for my future adventure game. Try using
the various functions of MapEdit to see what the mouse tools actually
look like on the screen.
By the way, if you want to see an actual program that used MapEdit, look
for BassTour by Dick Olsen, currently available on BBS's as BASSTR25.ZIP.
CGAExp, the other sample program, doesn't actually do anything useful but
demonstrates that the MouseTools can be used in CGA graphics as well as
EGA. Since there's less actual program surrounding the tools, you might
find it more useful for understanding the tools than MapEdit.
╔═══════════════════════════════════════════════════════════════════════════╗
║ Included Files ║
╚═══════════════════════════════════════════════════════════════════════════╝
The following files are included in MouseTools:
MOUSE.TPU Mouse driver interface and other basic mouse tools
MOUSERS2.TPU Mouse response tools
CONVERT.TPU Some convertion tools used by mapedit.pas
PALETTE.TPU Graphics initialization used by mapedit.pas
BOX.TPU Graphics utilities for popup boxes
CGAEXP.PAS Sample program using MouseTools (CGA)
CGAEXP.EXE Run-able version of sample program
MAPEDIT.PAS Sample program using MouseTools (EGA)
MAPEDIT.EXE Run-able version of sample program
CCMAP.PIC Sample data for mapedit.exe
SHAREWRE.TXT Explaination of shareware distribution
MOUSTOOL.DOC This file, the MouseTools documentation
╔═══════════════════════════════════════════════════════════════════════════╗
║ Available Software ║
╚═══════════════════════════════════════════════════════════════════════════╝
Other software which I've either written or contributed to:
EGATREK: Space strategy battle game, using full EGA graphics.
MAHJONGG: Solitaire game played with Chinese tiles. Supports
EGA and Hercules graphics; mouse optional. See reviews
in December 1988 "PCWorld" and April 1989 "Compute!".
MOUSTOOL: A collection of utilities for Turbo Pascal programmers
wishing to incorporate mouse input in their programs.
Sample programs included for both EGA and CGA graphics.
SOUNDPAS: A collection of utilities for Turbo Pascal programmers
to add music and sound effects to their programs. Includes
units for interrupt and real time sounds.
BASSTOUR: (Written by Dick Olsen). Game that simulates a fishing
tournament, including rod and lure selection. Runs in
EGA/CGA/Hercules graphics modes. Uses many of the
utilities from MOUSTOOL.